package com.zx.idc.backend.gui.scheduler.ins.filtermonitorlog.service;

import com.zx.idc.common.lang.ListUtil;
import com.zx.idc.common.util.TimeConversionUtils;
import com.zx.idc.ds.ins.entity.InsFilter;
import com.zx.idc.ds.ins.entity.InsFilterRule;
import com.zx.idc.ds.ins.service.IInsFilterRuleService;
import com.zx.idc.ds.ins.service.IInsFilterService;
import com.zx.idc.qc.constants.ScheduleJobConstants;
import com.zx.idc.qc.core.QuartzTaskService;
import com.zx.idc.qc.entity.TaskEntity;
import com.zx.idc.qc.exception.JobExistsException;
import com.zx.idc.qc.exception.QuartzJobException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 过滤指令job 服务类
 * smms 安全指令管理接口 11.7 违法信息安全管理指令
 * 服务于违法信息安全管理指令的生效时间和过期时间
 * 当生效时间到了的时候将规则发送给拦截器端执行
 * 当过期时间到了把拦截器端里面的这条规则删除
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class FilterInstructionJobService {
    private static final Logger LOG = LoggerFactory.getLogger(FilterInstructionJobService.class);

    @Autowired
    private QuartzTaskService quartzTaskService;

    @Autowired
    private IInsFilterService insFilterService;

    @Autowired
    private IInsFilterRuleService iInsFilterRuleService;

    /**
     * 生成任务调度
     * 1. 根据指令里面的生效时间，在生效时间到来的时候把指令规则发送给流量拦截器
     * 2. 根据指令里面的失效时间，在失效时间到来的时候把指令对应的拦截规则从拦截器中删除
     *
     * @param commandId 指令ID
     */
    public void generateScheduler(String commandId) throws JobExistsException, QuartzJobException {
        InsFilterRule insFilterRule = new InsFilterRule();
        insFilterRule.setInsId(commandId);
        List<InsFilterRule> insFilterRules = iInsFilterRuleService.selectList(insFilterRule);
        if (ListUtil.isEmpty(insFilterRules)) {
            LOG.error("指令不存在规则,执行结束,指令ID:{}", commandId);
            return;
        }
        InsFilter filterIns = insFilterService.selectById(commandId);
        filterIns.setInsFilterRules(insFilterRules);
        Map<String, Object> jobDataMap = new HashMap<>();
        jobDataMap.put(ScheduleJobConstants.INSTRUCTION_COMMAND_ID_KEY, commandId);
        jobDataMap.put(ScheduleJobConstants.INSTRUCTION_ENTITY, filterIns);
        //添加规则job
        Integer operationType = filterIns.getOperationType();
        if (InsFilter.OPERATION_TYPE_DELETE.equals(operationType)) {
            //添加删除任务
            TaskEntity expiredTask = getExpiredTask(filterIns, jobDataMap, filterIns.getEffectTime());
            quartzTaskService.deleteTask(expiredTask);
            quartzTaskService.addOnlyTimeTask(expiredTask);

        } else if (InsFilter.OPERATION_TYPE_ADD.equals(operationType)) {
            //添加规则job
            TaskEntity effectTask = getEffectTask(filterIns, jobDataMap, filterIns.getEffectTime());
            quartzTaskService.addOnlyTimeTask(effectTask);
            //删除规则job
            TaskEntity expiredTask = getExpiredTask(filterIns, jobDataMap, filterIns.getExpiredTime());
            quartzTaskService.addOnlyTimeTask(expiredTask);
        }
    }

    /**
     * 删除所有的调度任务
     *
     * @param commandId 指令ID
     */
    public void deleteScheduler(String commandId) throws QuartzJobException {
        InsFilter filterIns = insFilterService.selectById(commandId);
        Map<String, Object> jobDataMap = new HashMap<>();
        jobDataMap.put(ScheduleJobConstants.INSTRUCTION_COMMAND_ID_KEY, commandId);
        //删除任务
        TaskEntity expiredTask = getExpiredTask(filterIns, jobDataMap, LocalDateTime.now());
        quartzTaskService.deleteTask(expiredTask);
        TaskEntity effectTask = getEffectTask(filterIns, jobDataMap, LocalDateTime.now());
        quartzTaskService.deleteTask(effectTask);
    }

    private TaskEntity getEffectTask(InsFilter filterIns, Map<String, Object> jobDataMap, LocalDateTime time) {
        TaskEntity effectTask = new TaskEntity();
        effectTask.setJobClass("com.zx.idc.backend.gui.scheduler.ins.filtermonitorlog.job.AddFilterInstructionJob");
        Date effectTime = TimeConversionUtils.localDateTime2Date(time);
        effectTask.setStartTime(effectTime.getTime());
        effectTask.setJobGroup(ScheduleJobConstants.SCHEDULE_INSTRUCTION_GROUP);
        effectTask.setJobName(String.format("addFilterInstructionJob_%s", filterIns.getId()));
        effectTask.setJobDescription("添加监测指令规则任务");
        effectTask.setJobDataMap(jobDataMap);
        return effectTask;
    }

    private TaskEntity getExpiredTask(InsFilter filterIns, Map<String, Object> jobDataMap, LocalDateTime time) {
        //删除规则job
        TaskEntity expiredTask = new TaskEntity();
        expiredTask.setJobClass("com.zx.idc.backend.gui.scheduler.ins.filtermonitorlog.job.DelFilterInstructionJob");
        Date expiredTime = TimeConversionUtils.localDateTime2Date(time);
        expiredTask.setStartTime(expiredTime.getTime());
        expiredTask.setJobGroup(ScheduleJobConstants.SCHEDULE_INSTRUCTION_GROUP);
        expiredTask.setJobName(String.format("delFilterInstructionJob_%s", filterIns.getId()));
        expiredTask.setJobDescription("删除过滤指令规则任务");
        expiredTask.setJobDataMap(jobDataMap);
        return expiredTask;
    }

    /**
     * 生成删除规则任务调度
     * 1. 根据指令里面的失效时间，在失效时间到来的时候把指令对应的拦截规则从拦截器中删除
     *
     * @param commandId 指令ID
     */
    public void generateDeleteScheduler(String commandId) throws JobExistsException, QuartzJobException {
        InsFilter filterIns = insFilterService.selectById(commandId);
        InsFilterRule insFilterRule = new InsFilterRule();
        insFilterRule.setInsId(commandId);
        List<InsFilterRule> insFilterRules = iInsFilterRuleService.selectList(insFilterRule);
        if (ListUtil.isEmpty(insFilterRules)) {
            LOG.error("指令不存在规则,执行结束,指令ID:{}", filterIns.getId());
            return;
        }
        filterIns.setInsFilterRules(insFilterRules);
        Map<String, Object> jobDataMap = new HashMap<>();
        jobDataMap.put(ScheduleJobConstants.INSTRUCTION_COMMAND_ID_KEY, commandId);
        jobDataMap.put(ScheduleJobConstants.INSTRUCTION_ENTITY, filterIns);
        //添加删除任务
        TaskEntity expiredTask = getExpiredTask(filterIns, jobDataMap, filterIns.getExpiredTime());
        quartzTaskService.addOnlyTimeTask(expiredTask);
    }
}
